Acceleration Plot
computeThreshold <- function(x, xmin=min(x), xmax=max(x)) {
x <- x[x >= xmin & x <= xmax]
xArr <- matrix(x, nrow = 1, ncol = length(x))
threshold <- otsu(xArr, range=c(xmin, xmax))
return(threshold)
}
computeThresholdForAcceleration <- function(acc){
return(computeThreshold(acc, xmin=0, xmax=20))
}
findModes <- function(x) {
ux <- unique(x)
ux[which.max(tabulate(match(x, ux)))]
}
acc_thresholds <- vector(mode="list", length=length(persons))
names(acc_thresholds) <- persons
acc_sd_thresholds <- vector(mode="list", length=length(persons))
names(acc_sd_thresholds) <- persons
speed_sd_thresholds <- vector(mode="list", length=length(persons))
names(speed_sd_thresholds) <- persons
for (p in persons) {
pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
acc_th <- computeThresholdForAcceleration(pData$Acceleration)
acc_th_sd <- computeThresholdForAcceleration(pData$Acc_std)
speed_th_sd <- computeThresholdForAcceleration(pData$Speed_std)
acc_thresholds[[p]] <- as.numeric(acc_th)
acc_sd_thresholds[[p]] <- as.numeric(acc_th_sd)
speed_sd_thresholds[[p]] <- as.numeric(speed_th_sd)
acc_pl <- ggplot(pData, aes(x=Acceleration)) + geom_density() + geom_vline(aes(xintercept=acc_th), color="blue", linetype="dashed", size=1)
acc_sd_pl <- ggplot(pData, aes(x=Acc_std)) + geom_density() + geom_vline(aes(xintercept=acc_th_sd), color="red", linetype="dashed", size=1)
speed_sd_pl <- ggplot(pData, aes(x=Speed_std)) + geom_density() + geom_vline(aes(xintercept=speed_th_sd), color="red", linetype="dashed", size=1)
plot(speed_sd_pl)
print(paste0(p, " - Threshold (Acc) =", acc_th, " & (Acc SD) =", acc_th_sd, " & (Speed SD) =", acc_th_sd))
}
[1] "01 - Threshold (Acc) =8.2421875 & (Acc SD) =5.546875 & (Speed SD) =5.546875"
[1] "02 - Threshold (Acc) =9.9609375 & (Acc SD) =5.8203125 & (Speed SD) =5.8203125"
[1] "03 - Threshold (Acc) =9.1796875 & (Acc SD) =7.0703125 & (Speed SD) =7.0703125"
[1] "04 - Threshold (Acc) =10.1953125 & (Acc SD) =6.40625 & (Speed SD) =6.40625"
[1] "05 - Threshold (Acc) =9.9609375 & (Acc SD) =4.8046875 & (Speed SD) =4.8046875"
[1] "06 - Threshold (Acc) =10.234375 & (Acc SD) =6.4453125 & (Speed SD) =6.4453125"
[1] "07 - Threshold (Acc) =11.6015625 & (Acc SD) =7.3828125 & (Speed SD) =7.3828125"
[1] "09 - Threshold (Acc) =9.296875 & (Acc SD) =6.0546875 & (Speed SD) =6.0546875"
[1] "12 - Threshold (Acc) =9.7265625 & (Acc SD) =7.0703125 & (Speed SD) =7.0703125"
[1] "13 - Threshold (Acc) =10.5859375 & (Acc SD) =7.6171875 & (Speed SD) =7.6171875"
[1] "15 - Threshold (Acc) =9.1796875 & (Acc SD) =6.6796875 & (Speed SD) =6.6796875"
[1] "16 - Threshold (Acc) =9.5703125 & (Acc SD) =8.7109375 & (Speed SD) =8.7109375"
[1] "17 - Threshold (Acc) =9.1796875 & (Acc SD) =6.8359375 & (Speed SD) =6.8359375"
[1] "18 - Threshold (Acc) =10.9375 & (Acc SD) =6.5234375 & (Speed SD) =6.5234375"
[1] "22 - Threshold (Acc) =9.8046875 & (Acc SD) =5.6640625 & (Speed SD) =5.6640625"
[1] "24 - Threshold (Acc) =9.0234375 & (Acc SD) =7.2265625 & (Speed SD) =7.2265625"
[1] "29 - Threshold (Acc) =6.71875 & (Acc SD) =6.2109375 & (Speed SD) =6.2109375"
[1] "30 - Threshold (Acc) =8.90625 & (Acc SD) =6.5234375 & (Speed SD) =6.5234375"
[1] "31 - Threshold (Acc) =11.875 & (Acc SD) =6.2109375 & (Speed SD) =6.2109375"
[1] "32 - Threshold (Acc) =5.3515625 & (Acc SD) =7.1484375 & (Speed SD) =7.1484375"
[1] "41 - Threshold (Acc) =12.2265625 & (Acc SD) =5.8203125 & (Speed SD) =5.8203125"





















mean_pp <- vector(mode="list", length=length(persons))
names(mean_pp) <- persons
std_pp <- vector(mode="list", length=length(persons))
names(std_pp) <- persons
# Mean (Turning)
mean_pp_seg0 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0) <- persons
mean_pp_seg0_1 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_1) <- persons
mean_pp_seg0_2 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_2) <- persons
mean_pp_seg0_3 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_3) <- persons
mean_pp_seg0_4 <- vector(mode="list", length=length(persons))
names(mean_pp_seg0_4) <- persons
# Mean (Straight)
mean_pp_seg1 <- vector(mode="list", length=length(persons))
names(mean_pp_seg1) <- persons
mean_pp_seg2 <- vector(mode="list", length=length(persons))
names(mean_pp_seg2) <- persons
mean_pp_seg3 <- vector(mode="list", length=length(persons))
names(mean_pp_seg3) <- persons
mean_pp_seg4 <- vector(mode="list", length=length(persons))
names(mean_pp_seg4) <- persons
mean_pp_max <- vector(mode="list", length=length(persons))
names(mean_pp_max) <- persons
# SD (Turning)
std_pp_seg0 <- vector(mode="list", length=length(persons))
names(std_pp_seg0) <- persons
std_pp_seg0_1 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_1) <- persons
std_pp_seg0_2 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_2) <- persons
std_pp_seg0_3 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_3) <- persons
std_pp_seg0_4 <- vector(mode="list", length=length(persons))
names(std_pp_seg0_4) <- persons
# SD (Straight)
std_pp_seg1 <- vector(mode="list", length=length(persons))
names(std_pp_seg1) <- persons
std_pp_seg2 <- vector(mode="list", length=length(persons))
names(std_pp_seg2) <- persons
std_pp_seg3 <- vector(mode="list", length=length(persons))
names(std_pp_seg3) <- persons
std_pp_seg4 <- vector(mode="list", length=length(persons))
names(std_pp_seg4) <- persons
std_pp_max <- vector(mode="list", length=length(persons))
names(std_pp_max) <- persons
# Acceleration Partitioning
mean_pp_HighAcc <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc) <- persons
mean_pp_LowAcc <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc) <- persons
std_pp_HighAcc <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc) <- persons
std_pp_LowAcc <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc) <- persons
# Accel + Segmentation
mean_pp_HighAcc1 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc1) <- persons
mean_pp_LowAcc1 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc1) <- persons
std_pp_HighAcc1 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc1) <- persons
std_pp_LowAcc1 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc1) <- persons
mean_pp_HighAcc2 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc2) <- persons
mean_pp_LowAcc2 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc2) <- persons
std_pp_HighAcc2 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc2) <- persons
std_pp_LowAcc2 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc2) <- persons
mean_pp_HighAcc3 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc3) <- persons
mean_pp_LowAcc3 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc3) <- persons
std_pp_HighAcc3 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc3) <- persons
std_pp_LowAcc3 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc3) <- persons
mean_pp_HighAcc4 <- vector(mode="list", length=length(persons))
names(mean_pp_HighAcc4) <- persons
mean_pp_LowAcc4 <- vector(mode="list", length=length(persons))
names(mean_pp_LowAcc4) <- persons
std_pp_HighAcc4 <- vector(mode="list", length=length(persons))
names(std_pp_HighAcc4) <- persons
std_pp_LowAcc4 <- vector(mode="list", length=length(persons))
names(std_pp_LowAcc4) <- persons
for(p in persons) {
pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
pData_act3 <- pData[pData$Activity==3,]
# Data Partitioning
pData_seg0 <- pData[pData$Phase==0,]
pData_seg0_1 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 100 & pData$Time < 200,]
pData_seg0_2 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 200 & pData$Time < 300,]
pData_seg0_3 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 300 & pData$Time < 400,]
pData_seg0_4 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 400 & pData$Time < 500,]
pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
# pData_HighAcc <- pData[pData$Acceleration >= acc_thresholds[[p]],]
# pData_LowAcc <- pData[pData$Acceleration < acc_thresholds[[p]],]
pData_HighAcc <- pData[pData$Acc_std >= acc_sd_thresholds[[p]] | pData$Speed_std >= speed_sd_thresholds[[p]],]
pData_LowAcc <- pData[pData$Acc_std < acc_sd_thresholds[[p]] & pData$Speed_std < speed_sd_thresholds[[p]],]
pData_HighAcc1 <- pData_HighAcc[(pData_HighAcc$Distance < 350),]
pData_LowAcc1 <- pData_LowAcc[(pData_LowAcc$Distance < 350),]
pData_HighAcc2 <- pData_HighAcc[(pData_HighAcc$Distance >= 350 & pData_HighAcc$Distance < 700),]
pData_LowAcc2 <- pData_LowAcc[(pData_LowAcc$Distance >= 350 & pData_LowAcc$Distance < 700),]
pData_HighAcc3 <- pData_HighAcc[(pData_HighAcc$Distance >= 700 & pData_HighAcc$Distance < 1050),]
pData_LowAcc3 <- pData_LowAcc[(pData_LowAcc$Distance >= 700 & pData_LowAcc$Distance < 1050),]
pData_HighAcc4 <- pData_HighAcc[(pData_HighAcc$Distance >= 1050),]
pData_LowAcc4 <- pData_LowAcc[(pData_LowAcc$Distance >= 1050),]
mean_pp[[p]] <- mean(pData_act3$ppLogNormalized)
std_pp[[p]] <- sd(pData$ppLogNormalized)
mean_pp_seg0[[p]] <- mean(pData_seg0$ppLogNormalized)
mean_pp_seg0_1[[p]] <- mean(pData_seg0_1$ppLogNormalized)
mean_pp_seg0_2[[p]] <- mean(pData_seg0_2$ppLogNormalized)
mean_pp_seg0_3[[p]] <- mean(pData_seg0_3$ppLogNormalized)
mean_pp_seg0_4[[p]] <- mean(pData_seg0_4$ppLogNormalized)
mean_pp_seg1[[p]] <- mean(pData_seg1$ppLogNormalized)
mean_pp_seg2[[p]] <- mean(pData_seg2$ppLogNormalized)
mean_pp_seg3[[p]] <- mean(pData_seg3$ppLogNormalized)
mean_pp_seg4[[p]] <- mean(pData_seg4$ppLogNormalized)
mean_pp_max[[p]] <- max(mean_pp_seg1[[p]], mean_pp_seg2[[p]], mean_pp_seg3[[p]], mean_pp_seg4[[p]])
std_pp_seg0[[p]] <- sd(pData_seg0$ppLogNormalized)
std_pp_seg0_1[[p]] <- sd(pData_seg0_1$ppLogNormalized)
std_pp_seg0_2[[p]] <- sd(pData_seg0_2$ppLogNormalized)
std_pp_seg0_3[[p]] <- sd(pData_seg0_3$ppLogNormalized)
std_pp_seg0_4[[p]] <- sd(pData_seg0_4$ppLogNormalized)
std_pp_seg1[[p]] <- sd(pData_seg1$ppLogNormalized)
std_pp_seg2[[p]] <- sd(pData_seg2$ppLogNormalized)
std_pp_seg3[[p]] <- sd(pData_seg3$ppLogNormalized)
std_pp_seg4[[p]] <- sd(pData_seg4$ppLogNormalized)
std_pp_max[[p]] <- max(std_pp_seg1[[p]], std_pp_seg2[[p]], std_pp_seg3[[p]], std_pp_seg4[[p]])
# Acceleration
mean_pp_HighAcc[[p]] <- mean(pData_HighAcc$ppNext)
mean_pp_LowAcc[[p]] <- mean(pData_LowAcc$ppNext)
std_pp_HighAcc[[p]] <- sd(pData_HighAcc$ppNext)
std_pp_LowAcc[[p]] <- sd(pData_LowAcc$ppNext)
mean_pp_HighAcc1[[p]] <- mean(pData_HighAcc1$ppNext)
mean_pp_LowAcc1[[p]] <- mean(pData_LowAcc1$ppNext)
std_pp_HighAcc1[[p]] <- sd(pData_HighAcc1$ppNext)
std_pp_LowAcc1[[p]] <- sd(pData_LowAcc1$ppNext)
mean_pp_HighAcc2[[p]] <- mean(pData_HighAcc2$ppNext)
mean_pp_LowAcc2[[p]] <- mean(pData_LowAcc2$ppNext)
std_pp_HighAcc2[[p]] <- sd(pData_HighAcc2$ppNext)
std_pp_LowAcc2[[p]] <- sd(pData_LowAcc2$ppNext)
mean_pp_HighAcc3[[p]] <- mean(pData_HighAcc3$ppNext)
mean_pp_LowAcc3[[p]] <- mean(pData_LowAcc3$ppNext)
std_pp_HighAcc3[[p]] <- sd(pData_HighAcc3$ppNext)
std_pp_LowAcc3[[p]] <- sd(pData_LowAcc3$ppNext)
mean_pp_HighAcc4[[p]] <- mean(pData_HighAcc4$ppNext)
mean_pp_LowAcc4[[p]] <- mean(pData_LowAcc4$ppNext)
std_pp_HighAcc4[[p]] <- sd(pData_HighAcc4$ppNext)
std_pp_LowAcc4[[p]] <- sd(pData_LowAcc4$ppNext)
}
plt_AllAcc <- vector(mode="list", length=length(persons))
names(plt_AllAcc) <- persons
COLOR_ACC = "#02A3C8"
COLOR_PP = "#F28E8E"
COLOR_BRAKE = "#888888"
y1 <- list(
tickfont = list(color = COLOR_ACC),
title="Degree",
range=c(0, max(all_Drive3$Acceleration))
)
y2 <- list(
tickfont = list(color = COLOR_PP),
overlaying = "y",
side = "right",
title = "Log Perspiration",
showgrid = FALSE,
range=c(-0.6, 0.9)
# range=c(min(all_Drive3$ppLogNormalized), max(all_Drive3$ppLogNormalized))
)
for (p in persons) {
pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
pData_seg0 <- pData[pData$Phase==0,]
pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
plot_Acc <- plot_ly(pData, x = ~Time, height=400, width=900) %>%
# add_trace(name="Acceleration", y = ~Acceleration, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_ACC)) %>%
add_trace(name="PP", y = ~ppLogNormalized, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_PP), yaxis = "y2") %>%
add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp[[p]], yend = mean_pp[[p]],
yaxis = "y2", name="Avg. PP (straight)",
line=list(color="darkgray", dash = 'dot')) %>%
add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp_seg0[[p]], yend = mean_pp_seg0[[p]],
yaxis = "y2", name="Avg. PP (turning)",
line=list(color="black", dash = 'dot')) %>%
add_segments(x = min(pData_seg1$Time), xend = max(pData_seg1$Time), y = mean_pp_seg1[[p]], yend = mean_pp_seg1[[p]],
yaxis = "y2", name="Avg. PP (1st part)",
line=list(color="red", dash = 'dot')) %>%
add_segments(x = min(pData_seg2$Time), xend = max(pData_seg2$Time), y = mean_pp_seg2[[p]], yend = mean_pp_seg2[[p]],
yaxis = "y2", name="Avg. PP (2nd part)",
line=list(color="green", dash = 'dot')) %>%
add_segments(x = min(pData_seg3$Time), xend = max(pData_seg3$Time), y = mean_pp_seg3[[p]], yend = mean_pp_seg3[[p]],
yaxis = "y2", name="Avg. PP (3rd part)",
line=list(color="blue", dash = 'dot')) %>%
add_segments(x = min(pData_seg4$Time), xend = max(pData_seg4$Time), y = mean_pp_seg4[[p]], yend = mean_pp_seg4[[p]],
yaxis = "y2", name="Avg. PP (4th part)",
line=list(color="purple", dash = 'dot')) %>%
layout(
title=paste0("Subject #", p),
xaxis=list(title="Time [s]", range=c(0)),
yaxis=y1,
yaxis2=y2,
margin = list(l = 50, r = 50, b = 50, t = 50, pad = 4),
legend = list(x = 0.5, xanchor = "center", y = 0.2, bgcolor = "rgba(0,0,0,0)", title="Metric", orientation = "h"),
autosize = F
)
plt_AllAcc[[p]] <- plot_Acc
}
htmltools::tagList(plt_AllAcc)
NUMBER_OF_CLUSTERS = 3
color_darkpink = "#e75480"
CLUSTER_BRANCH_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]
CLUSTER_LABEL_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]
dfPP <- as.data.frame(cbind(
unlist(mean_pp),
unlist(std_pp),
unlist(mean_pp_seg0),
unlist(mean_pp_seg1),
unlist(mean_pp_seg2),
unlist(mean_pp_seg3),
unlist(mean_pp_seg4),
unlist(mean_pp_max),
unlist(std_pp_seg0),
unlist(std_pp_seg1),
unlist(std_pp_seg2),
unlist(std_pp_seg3),
unlist(std_pp_seg4),
unlist(std_pp_max),
unlist(mean_pp_seg0_1),
unlist(mean_pp_seg0_2),
unlist(mean_pp_seg0_3),
unlist(mean_pp_seg0_4),
unlist(std_pp_seg0_1),
unlist(std_pp_seg0_2),
unlist(std_pp_seg0_3),
unlist(std_pp_seg0_4),
unlist(mean_pp_HighAcc),
unlist(mean_pp_LowAcc),
unlist(std_pp_HighAcc),
unlist(std_pp_LowAcc),
unlist(mean_pp_HighAcc1),
unlist(mean_pp_LowAcc1),
unlist(std_pp_HighAcc1),
unlist(std_pp_LowAcc1),
unlist(mean_pp_HighAcc2),
unlist(mean_pp_LowAcc2),
unlist(std_pp_HighAcc2),
unlist(std_pp_LowAcc2),
unlist(mean_pp_HighAcc3),
unlist(mean_pp_LowAcc3),
unlist(std_pp_HighAcc3),
unlist(std_pp_LowAcc3),
unlist(mean_pp_HighAcc4),
unlist(mean_pp_LowAcc4),
unlist(std_pp_HighAcc4),
unlist(std_pp_LowAcc4)
))
names(dfPP) <- c("MeanPP", "StdPP",
"MeanPP_Seg0", "MeanPP_Seg1", "MeanPP_Seg2", "MeanPP_Seg3", "MeanPP_Seg4", "MeanPP_SegMax",
"StdPP_Seg0", "StdPP_Seg1", "StdPP_Seg2", "StdPP_Seg3", "StdPP_Seg4", "StdPP_SegMax",
"MeanPP_Seg0_1", "MeanPP_Seg0_2", "MeanPP_Seg0_3", "MeanPP_Seg0_4",
"StdPP_Seg0_1", "StdPP_Seg0_2", "StdPP_Seg0_3", "StdPP_Seg0_4",
"MeanPP_AccHigh", " MeanPP_AccLow", "StdPP_AccHigh", "StdPP_AccLow",
"MeanPP_AccHigh1", " MeanPP_AccLow1", "StdPP_AccHigh1", "StdPP_AccLow1",
"MeanPP_AccHigh2", " MeanPP_AccLow2", "StdPP_AccHigh2", "StdPP_AccLow2",
"MeanPP_AccHigh3", " MeanPP_AccLow3", "StdPP_AccHigh3", "StdPP_AccLow3",
"MeanPP_AccHigh4", " MeanPP_AccLow4", "StdPP_AccHigh4", "StdPP_AccLow4")
behavioralMatrixClustering <- as.matrix(dfPP)
distMatrix <- dist(behavioralMatrixClustering)
hresults <- distMatrix %>% hclust(method="average")
hc <- hresults %>%
as.dendrogram %>%
set("nodes_cex", NUMBER_OF_CLUSTERS) %>%
set("labels_col", value = CLUSTER_LABEL_COLORS, k=NUMBER_OF_CLUSTERS) %>%
# set("leaves_pch", 19) %>%
# set("leaves_col", value = c("gray"), k=NUMBER_OF_CLUSTERS) %>%
set("branches_k_color", value=CLUSTER_BRANCH_COLORS, k=NUMBER_OF_CLUSTERS)
plot(hc)
legend("topright",
title="Drive=Motoric \nHierachical Clustering",
legend = c("Group 1", "Group 2", "Group 3"),
col = c("darkred", "pink" , "blue"),
pch = c(20,20,20), bty = "n", pt.cex = 1.5, cex = 0.8 ,
text.col = "black", horiz = FALSE, inset = c(0.4, 0.1))

Clustering with SD of PP
library(dendextend)
clusteringDf <- dfPP %>% select(StdPP)
NUMBER_OF_CLUSTERS = 3
color_darkpink = "#e75480"
CLUSTER_BRANCH_COLORS <- c("darkred", "blue", "red")[1:NUMBER_OF_CLUSTERS]
CLUSTER_LABEL_COLORS <- c("darkred", "blue", "red")[1:NUMBER_OF_CLUSTERS]
behavioralMatrixClustering <- as.matrix(clusteringDf)
rownames(behavioralMatrixClustering) <- paste0("#", persons)
distMatrix <- dist(behavioralMatrixClustering)
hresults <- distMatrix %>% hclust
hc <- hresults %>%
as.dendrogram %>%
set("nodes_cex", NUMBER_OF_CLUSTERS) %>%
set("labels_col", value = CLUSTER_LABEL_COLORS, k=NUMBER_OF_CLUSTERS) %>%
# set("leaves_pch", 19) %>%
# set("leaves_col", value = c("gray"), k=NUMBER_OF_CLUSTERS) %>%
set("branches_k_color", value=CLUSTER_BRANCH_COLORS, k=NUMBER_OF_CLUSTERS)
plot(hc)
legend("topright",
title="Drive=Motoric \nChange of Arousal",
legend = c("Exceptional SD" , "Low SD" , "High SD"),
col = c("darkred", "blue" , "red"),
pch = c(20,20,20), bty = "n", pt.cex = 1.5, cex = 0.8 ,
text.col = "black", horiz = FALSE, inset = c(0.0, 0.1))

library(cluster)
silhouette_score <- function(k){
km <- kmeans(clusteringDf, centers = k, nstart=25)
ss <- silhouette(km$cluster, dist(clusteringDf))
mean(ss[, 3])
}
k <- 2:10
avg_sil <- sapply(k, silhouette_score)
plot(k, type='b', avg_sil, xlab='Number of clusters', ylab='Average Silhouette Scores', frame=FALSE)

# Store clustering data
dfx <- dfPP
dfx <- cbind(persons, dfx)
names(dfx) <- c("Subject" , names(dfPP))
write.csv(dfx, outputFile, row.names = F)
Linear Model
sampledData <- getSampleSegmentedData(NA, all_Drive3, window=2)
linearModelOnline <- lmer(ppNext ~
(1 | Subject)
+ Speed_u
+ Speed_std
+ Acc_u
+ Acc_std
+ Brake_u
+ Brake_std
+ Steering_u
+ Steering_std,
data=sampledData, REML = T)
# lmer(ppLogNormalized ~ (1 | Subject) + Speed_u + Speed_std + Acc_u + Acc_std + Brake_u + Brake_std + Steering_u + Steering_std + HR + BR, data = pData, REML = T)
# anova(model)
summary(linearModelOnline)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: ppNext ~ (1 | Subject) + Speed_u + Speed_std + Acc_u + Acc_std + Brake_u + Brake_std + Steering_u + Steering_std
Data: sampledData
REML criterion at convergence: -16082.8
Scaled residuals:
Min 1Q Median 3Q Max
-5.3993 -0.5557 -0.0265 0.5139 5.3259
Random effects:
Groups Name Variance Std.Dev.
Subject (Intercept) 0.010549 0.10271
Residual 0.002354 0.04852
Number of obs: 5089, groups: Subject, 21
Fixed effects:
Estimate Std. Error df t value Pr(>|t|)
(Intercept) 1.977e-01 2.369e-02 2.492e+01 8.345 1.11e-08 ***
Speed_u -4.543e-03 2.488e-04 5.063e+03 -18.261 < 2e-16 ***
Speed_std -7.174e-03 7.967e-04 5.063e+03 -9.004 < 2e-16 ***
Acc_u 9.210e-04 3.214e-04 5.068e+03 2.866 0.00418 **
Acc_std 2.682e-03 2.887e-04 5.061e+03 9.291 < 2e-16 ***
Brake_u 1.994e-03 4.416e-04 5.060e+03 4.516 6.44e-06 ***
Brake_std -1.364e-04 4.602e-04 5.061e+03 -0.296 0.76696
Steering_u -1.007e-05 8.624e-06 5.061e+03 -1.168 0.24300
Steering_std -4.644e-05 2.399e-05 5.061e+03 -1.935 0.05299 .
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Correlation of Fixed Effects:
(Intr) Speed_ Spd_st Acc_u Acc_st Brake_ Brk_st Sterng_
Speed_u -0.257
Speed_std -0.046 -0.006
Acc_u -0.097 -0.300 0.014
Acc_std -0.098 0.196 -0.064 -0.047
Brake_u -0.098 0.183 -0.098 0.195 0.194
Brake_std 0.012 0.186 -0.042 -0.261 -0.418 -0.783
Steering_u -0.041 0.143 0.053 -0.041 0.011 0.099 -0.007
Steerng_std -0.211 0.500 -0.122 0.225 0.440 0.256 -0.330 -0.107
plot(linearModelOnline)

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnNvdXJjZSgnLi4vc2V0dGluZ3Mvc2V0dGluZ3MuUicpCnNvdXJjZSgnY29tbW9uRnVuY3Rpb25zLlInKQpgYGAKCmBgYHtyfQpwZXJzb25zIDwtIFNFTEVDVEVEX1NVQkpFQ1RTCmRyaXZlIDwtIDMKaW5wdXRGaWxlIDwtIHN0cl9pbnRlcnAoJy4uL2RhdGEvcHJvY2Vzc2VkL2Rpc3RhbmNld2lzZS9UVDFfRHJpdmVfJHtkcml2ZX1fJHtkaXN0UHJldn1tXyR7ZGlzdE5leHR9bS5jc3YnLCBsaXN0KGRyaXZlPWRyaXZlLCBkaXN0UHJldj1ESVNUQU5DRV9QUkVWLCBkaXN0TmV4dD1ESVNUQU5DRV9ORVhUKSkKb3V0cHV0RmlsZSA8LSBzdHJfaW50ZXJwKCIuLi9kYXRhL3Byb2Nlc3NlZC9hbmFseXNpcy9UVDFfRHJpdmVfJHtkcml2ZX1fUFBfJHtkaXN0UHJldn1tXyR7ZGlzdE5leHR9bS5jc3YiLCBsaXN0KGRyaXZlPWRyaXZlLCBkaXN0UHJldj1ESVNUQU5DRV9QUkVWLCBkaXN0TmV4dD1ESVNUQU5DRV9ORVhUKSkKCmFsbF9Ecml2ZTMgPC0gcmVhZC5jc3YoaW5wdXRGaWxlKQphbGxfRHJpdmUzJFN1YmplY3QgPC0gYXMuZmFjdG9yKGFsbF9Ecml2ZTMkU3ViamVjdCkKYWxsX0RyaXZlMyRsb2dQZXJzcGlyYXRpb24gPC0gbG9nKGFsbF9Ecml2ZTMkUGVyc3BpcmF0aW9uKQpgYGAKCiMgQWNjZWxlcmF0aW9uIFBsb3QKYGBge3J9CmNvbXB1dGVUaHJlc2hvbGQgPC0gZnVuY3Rpb24oeCwgeG1pbj1taW4oeCksIHhtYXg9bWF4KHgpKSB7CiAgeCA8LSB4W3ggPj0geG1pbiAmIHggPD0geG1heF0KICB4QXJyIDwtIG1hdHJpeCh4LCBucm93ID0gMSwgbmNvbCA9IGxlbmd0aCh4KSkKICB0aHJlc2hvbGQgPC0gb3RzdSh4QXJyLCByYW5nZT1jKHhtaW4sIHhtYXgpKQogIHJldHVybih0aHJlc2hvbGQpCn0KY29tcHV0ZVRocmVzaG9sZEZvckFjY2VsZXJhdGlvbiA8LSBmdW5jdGlvbihhY2MpewogIHJldHVybihjb21wdXRlVGhyZXNob2xkKGFjYywgeG1pbj0wLCB4bWF4PTIwKSkKfQpmaW5kTW9kZXMgPC0gZnVuY3Rpb24oeCkgewogIHV4IDwtIHVuaXF1ZSh4KQogIHV4W3doaWNoLm1heCh0YWJ1bGF0ZShtYXRjaCh4LCB1eCkpKV0KfQpgYGAKCmBgYHtyfQphY2NfdGhyZXNob2xkcyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhhY2NfdGhyZXNob2xkcykgPC0gcGVyc29ucwoKYWNjX3NkX3RocmVzaG9sZHMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoYWNjX3NkX3RocmVzaG9sZHMpIDwtIHBlcnNvbnMKCnNwZWVkX3NkX3RocmVzaG9sZHMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3BlZWRfc2RfdGhyZXNob2xkcykgPC0gcGVyc29ucwoKZm9yIChwIGluIHBlcnNvbnMpIHsKICBwRGF0YSA8LSBhbGxfRHJpdmUzWyhhbGxfRHJpdmUzJFN1YmplY3Q9PWFzLmludGVnZXIocCkgfCBhbGxfRHJpdmUzJFN1YmplY3Q9PXApLF0KICBhY2NfdGggPC0gY29tcHV0ZVRocmVzaG9sZEZvckFjY2VsZXJhdGlvbihwRGF0YSRBY2NlbGVyYXRpb24pCiAgYWNjX3RoX3NkIDwtIGNvbXB1dGVUaHJlc2hvbGRGb3JBY2NlbGVyYXRpb24ocERhdGEkQWNjX3N0ZCkKICBzcGVlZF90aF9zZCA8LSBjb21wdXRlVGhyZXNob2xkRm9yQWNjZWxlcmF0aW9uKHBEYXRhJFNwZWVkX3N0ZCkKICBhY2NfdGhyZXNob2xkc1tbcF1dIDwtIGFzLm51bWVyaWMoYWNjX3RoKQogIGFjY19zZF90aHJlc2hvbGRzW1twXV0gPC0gYXMubnVtZXJpYyhhY2NfdGhfc2QpCiAgc3BlZWRfc2RfdGhyZXNob2xkc1tbcF1dIDwtIGFzLm51bWVyaWMoc3BlZWRfdGhfc2QpCiAgCiAgYWNjX3BsIDwtIGdncGxvdChwRGF0YSwgYWVzKHg9QWNjZWxlcmF0aW9uKSkgKyBnZW9tX2RlbnNpdHkoKSArIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9YWNjX3RoKSwgY29sb3I9ImJsdWUiLCBsaW5ldHlwZT0iZGFzaGVkIiwgc2l6ZT0xKQogIGFjY19zZF9wbCA8LSBnZ3Bsb3QocERhdGEsIGFlcyh4PUFjY19zdGQpKSArIGdlb21fZGVuc2l0eSgpICsgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1hY2NfdGhfc2QpLCBjb2xvcj0icmVkIiwgbGluZXR5cGU9ImRhc2hlZCIsIHNpemU9MSkKICBzcGVlZF9zZF9wbCA8LSBnZ3Bsb3QocERhdGEsIGFlcyh4PVNwZWVkX3N0ZCkpICsgZ2VvbV9kZW5zaXR5KCkgKyBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0PXNwZWVkX3RoX3NkKSwgY29sb3I9InJlZCIsIGxpbmV0eXBlPSJkYXNoZWQiLCBzaXplPTEpCiAgCiAgcGxvdChzcGVlZF9zZF9wbCkKICBwcmludChwYXN0ZTAocCwgIiAtIFRocmVzaG9sZCAoQWNjKSA9IiwgYWNjX3RoLCAiICYgKEFjYyBTRCkgPSIsIGFjY190aF9zZCwgIiAmIChTcGVlZCBTRCkgPSIsIGFjY190aF9zZCkpCiAgCn0KYGBgCgpgYGB7cn0KbWVhbl9wcCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwKSA8LSBwZXJzb25zCgpzdGRfcHAgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwKSA8LSBwZXJzb25zCgojIE1lYW4gKFR1cm5pbmcpCm1lYW5fcHBfc2VnMCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzApIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWcwXzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcwXzEpIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWcwXzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcwXzIpIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWcwXzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcwXzMpIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWcwXzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcwXzQpIDwtIHBlcnNvbnMKCiMgTWVhbiAoU3RyYWlnaHQpCm1lYW5fcHBfc2VnMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzEpIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWcyIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMikgPC0gcGVyc29ucwptZWFuX3BwX3NlZzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWczKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzQpIDwtIHBlcnNvbnMKbWVhbl9wcF9tYXggPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9tYXgpIDwtIHBlcnNvbnMKCiMgU0QgKFR1cm5pbmcpCnN0ZF9wcF9zZWcwIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcwKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWcwXzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzBfMSkgPC0gcGVyc29ucwpzdGRfcHBfc2VnMF8yIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcwXzIpIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzBfMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMF8zKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWcwXzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzBfNCkgPC0gcGVyc29ucwoKIyBTRCAoU3RyYWlnaHQpCnN0ZF9wcF9zZWcxIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcxKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWcyIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcyKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWczIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWczKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWc0IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWc0KSA8LSBwZXJzb25zCnN0ZF9wcF9tYXggPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX21heCkgPC0gcGVyc29ucwoKIyBBY2NlbGVyYXRpb24gUGFydGl0aW9uaW5nCm1lYW5fcHBfSGlnaEFjYyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0hpZ2hBY2MpIDwtIHBlcnNvbnMKbWVhbl9wcF9Mb3dBY2MgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9Mb3dBY2MpIDwtIHBlcnNvbnMKCnN0ZF9wcF9IaWdoQWNjIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9IaWdoQWNjKSA8LSBwZXJzb25zCnN0ZF9wcF9Mb3dBY2MgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0xvd0FjYykgPC0gcGVyc29ucwoKIyBBY2NlbCArIFNlZ21lbnRhdGlvbgptZWFuX3BwX0hpZ2hBY2MxIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfSGlnaEFjYzEpIDwtIHBlcnNvbnMKbWVhbl9wcF9Mb3dBY2MxIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfTG93QWNjMSkgPC0gcGVyc29ucwpzdGRfcHBfSGlnaEFjYzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0hpZ2hBY2MxKSA8LSBwZXJzb25zCnN0ZF9wcF9Mb3dBY2MxIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9Mb3dBY2MxKSA8LSBwZXJzb25zCgptZWFuX3BwX0hpZ2hBY2MyIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfSGlnaEFjYzIpIDwtIHBlcnNvbnMKbWVhbl9wcF9Mb3dBY2MyIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfTG93QWNjMikgPC0gcGVyc29ucwpzdGRfcHBfSGlnaEFjYzIgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0hpZ2hBY2MyKSA8LSBwZXJzb25zCnN0ZF9wcF9Mb3dBY2MyIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9Mb3dBY2MyKSA8LSBwZXJzb25zCgptZWFuX3BwX0hpZ2hBY2MzIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfSGlnaEFjYzMpIDwtIHBlcnNvbnMKbWVhbl9wcF9Mb3dBY2MzIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfTG93QWNjMykgPC0gcGVyc29ucwpzdGRfcHBfSGlnaEFjYzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0hpZ2hBY2MzKSA8LSBwZXJzb25zCnN0ZF9wcF9Mb3dBY2MzIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9Mb3dBY2MzKSA8LSBwZXJzb25zCgptZWFuX3BwX0hpZ2hBY2M0IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfSGlnaEFjYzQpIDwtIHBlcnNvbnMKbWVhbl9wcF9Mb3dBY2M0IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfTG93QWNjNCkgPC0gcGVyc29ucwpzdGRfcHBfSGlnaEFjYzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX0hpZ2hBY2M0KSA8LSBwZXJzb25zCnN0ZF9wcF9Mb3dBY2M0IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9Mb3dBY2M0KSA8LSBwZXJzb25zCgpmb3IocCBpbiBwZXJzb25zKSB7CiAgcERhdGEgPC0gYWxsX0RyaXZlM1soYWxsX0RyaXZlMyRTdWJqZWN0PT1hcy5pbnRlZ2VyKHApIHwgYWxsX0RyaXZlMyRTdWJqZWN0PT1wKSxdCiAgcERhdGFfYWN0MyA8LSBwRGF0YVtwRGF0YSRBY3Rpdml0eT09MyxdCiAgCiAgIyBEYXRhIFBhcnRpdGlvbmluZwogIHBEYXRhX3NlZzAgPC0gcERhdGFbcERhdGEkUGhhc2U9PTAsXQogIHBEYXRhX3NlZzBfMSA8LSBwRGF0YVtwRGF0YSRBY3Rpdml0eT09MCAmIHBEYXRhJFBoYXNlPT0wICYgcERhdGEkVGltZSA+IDEwMCAmIHBEYXRhJFRpbWUgPCAyMDAsXQogIHBEYXRhX3NlZzBfMiA8LSBwRGF0YVtwRGF0YSRBY3Rpdml0eT09MCAmIHBEYXRhJFBoYXNlPT0wICYgcERhdGEkVGltZSA+IDIwMCAmIHBEYXRhJFRpbWUgPCAzMDAsXQogIHBEYXRhX3NlZzBfMyA8LSBwRGF0YVtwRGF0YSRBY3Rpdml0eT09MCAmIHBEYXRhJFBoYXNlPT0wICYgcERhdGEkVGltZSA+IDMwMCAmIHBEYXRhJFRpbWUgPCA0MDAsXQogIHBEYXRhX3NlZzBfNCA8LSBwRGF0YVtwRGF0YSRBY3Rpdml0eT09MCAmIHBEYXRhJFBoYXNlPT0wICYgcERhdGEkVGltZSA+IDQwMCAmIHBEYXRhJFRpbWUgPCA1MDAsXQogIAogIHBEYXRhX3NlZzEgPC0gcERhdGFbcERhdGEkUGhhc2U9PTEgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAxMTAsXQogIHBEYXRhX3NlZzIgPC0gcERhdGFbcERhdGEkUGhhc2U9PTIgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAyNTAsXQogIHBEYXRhX3NlZzMgPC0gcERhdGFbcERhdGEkUGhhc2U9PTMgJiBwRGF0YSRBY3Rpdml0eT09MyAmIHBEYXRhJFRpbWUgPCAzNTAsXQogIHBEYXRhX3NlZzQgPC0gcERhdGFbcERhdGEkUGhhc2U9PTQgJiBwRGF0YSRBY3Rpdml0eT09MyxdCiAgCiAgIyBwRGF0YV9IaWdoQWNjIDwtIHBEYXRhW3BEYXRhJEFjY2VsZXJhdGlvbiA+PSBhY2NfdGhyZXNob2xkc1tbcF1dLF0KICAjIHBEYXRhX0xvd0FjYyA8LSBwRGF0YVtwRGF0YSRBY2NlbGVyYXRpb24gPCBhY2NfdGhyZXNob2xkc1tbcF1dLF0KICBwRGF0YV9IaWdoQWNjIDwtIHBEYXRhW3BEYXRhJEFjY19zdGQgPj0gYWNjX3NkX3RocmVzaG9sZHNbW3BdXSB8IHBEYXRhJFNwZWVkX3N0ZCA+PSBzcGVlZF9zZF90aHJlc2hvbGRzW1twXV0sXQogIHBEYXRhX0xvd0FjYyA8LSBwRGF0YVtwRGF0YSRBY2Nfc3RkIDwgYWNjX3NkX3RocmVzaG9sZHNbW3BdXSAmIHBEYXRhJFNwZWVkX3N0ZCA8IHNwZWVkX3NkX3RocmVzaG9sZHNbW3BdXSxdCiAgCiAgcERhdGFfSGlnaEFjYzEgPC0gcERhdGFfSGlnaEFjY1socERhdGFfSGlnaEFjYyREaXN0YW5jZSA8IDM1MCksXQogIHBEYXRhX0xvd0FjYzEgPC0gcERhdGFfTG93QWNjWyhwRGF0YV9Mb3dBY2MkRGlzdGFuY2UgPCAzNTApLF0KICBwRGF0YV9IaWdoQWNjMiA8LSBwRGF0YV9IaWdoQWNjWyhwRGF0YV9IaWdoQWNjJERpc3RhbmNlID49IDM1MCAmIHBEYXRhX0hpZ2hBY2MkRGlzdGFuY2UgPCA3MDApLF0KICBwRGF0YV9Mb3dBY2MyIDwtIHBEYXRhX0xvd0FjY1socERhdGFfTG93QWNjJERpc3RhbmNlID49IDM1MCAmIHBEYXRhX0xvd0FjYyREaXN0YW5jZSA8IDcwMCksXQogIHBEYXRhX0hpZ2hBY2MzIDwtIHBEYXRhX0hpZ2hBY2NbKHBEYXRhX0hpZ2hBY2MkRGlzdGFuY2UgPj0gNzAwICYgcERhdGFfSGlnaEFjYyREaXN0YW5jZSA8IDEwNTApLF0KICBwRGF0YV9Mb3dBY2MzIDwtIHBEYXRhX0xvd0FjY1socERhdGFfTG93QWNjJERpc3RhbmNlID49IDcwMCAmIHBEYXRhX0xvd0FjYyREaXN0YW5jZSA8IDEwNTApLF0KICBwRGF0YV9IaWdoQWNjNCA8LSBwRGF0YV9IaWdoQWNjWyhwRGF0YV9IaWdoQWNjJERpc3RhbmNlID49IDEwNTApLF0KICBwRGF0YV9Mb3dBY2M0IDwtIHBEYXRhX0xvd0FjY1socERhdGFfTG93QWNjJERpc3RhbmNlID49IDEwNTApLF0KICAKICBtZWFuX3BwW1twXV0gPC0gbWVhbihwRGF0YV9hY3QzJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBbW3BdXSA8LSBzZChwRGF0YSRwcExvZ05vcm1hbGl6ZWQpCiAgCiAgbWVhbl9wcF9zZWcwW1twXV0gPC0gbWVhbihwRGF0YV9zZWcwJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzBfMVtbcF1dIDwtIG1lYW4ocERhdGFfc2VnMF8xJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzBfMltbcF1dIDwtIG1lYW4ocERhdGFfc2VnMF8yJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzBfM1tbcF1dIDwtIG1lYW4ocERhdGFfc2VnMF8zJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzBfNFtbcF1dIDwtIG1lYW4ocERhdGFfc2VnMF80JHBwTG9nTm9ybWFsaXplZCkKICAKICBtZWFuX3BwX3NlZzFbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzEkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnMltbcF1dIDwtIG1lYW4ocERhdGFfc2VnMiRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWczW1twXV0gPC0gbWVhbihwRGF0YV9zZWczJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzRbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzQkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfbWF4W1twXV0gPC0gbWF4KG1lYW5fcHBfc2VnMVtbcF1dLCBtZWFuX3BwX3NlZzJbW3BdXSwgbWVhbl9wcF9zZWczW1twXV0sIG1lYW5fcHBfc2VnNFtbcF1dKQogIAogIHN0ZF9wcF9zZWcwW1twXV0gPC0gc2QocERhdGFfc2VnMCRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzBfMVtbcF1dIDwtIHNkKHBEYXRhX3NlZzBfMSRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzBfMltbcF1dIDwtIHNkKHBEYXRhX3NlZzBfMiRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzBfM1tbcF1dIDwtIHNkKHBEYXRhX3NlZzBfMyRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzBfNFtbcF1dIDwtIHNkKHBEYXRhX3NlZzBfNCRwcExvZ05vcm1hbGl6ZWQpCiAgCiAgc3RkX3BwX3NlZzFbW3BdXSA8LSBzZChwRGF0YV9zZWcxJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnMltbcF1dIDwtIHNkKHBEYXRhX3NlZzIkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWczW1twXV0gPC0gc2QocERhdGFfc2VnMyRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzRbW3BdXSA8LSBzZChwRGF0YV9zZWc0JHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfbWF4W1twXV0gPC0gbWF4KHN0ZF9wcF9zZWcxW1twXV0sIHN0ZF9wcF9zZWcyW1twXV0sIHN0ZF9wcF9zZWczW1twXV0sIHN0ZF9wcF9zZWc0W1twXV0pCiAgCiAgIyBBY2NlbGVyYXRpb24KICBtZWFuX3BwX0hpZ2hBY2NbW3BdXSA8LSBtZWFuKHBEYXRhX0hpZ2hBY2MkcHBOZXh0KQogIG1lYW5fcHBfTG93QWNjW1twXV0gPC0gbWVhbihwRGF0YV9Mb3dBY2MkcHBOZXh0KQogIHN0ZF9wcF9IaWdoQWNjW1twXV0gPC0gc2QocERhdGFfSGlnaEFjYyRwcE5leHQpCiAgc3RkX3BwX0xvd0FjY1tbcF1dIDwtIHNkKHBEYXRhX0xvd0FjYyRwcE5leHQpCiAgCiAgbWVhbl9wcF9IaWdoQWNjMVtbcF1dIDwtIG1lYW4ocERhdGFfSGlnaEFjYzEkcHBOZXh0KQogIG1lYW5fcHBfTG93QWNjMVtbcF1dIDwtIG1lYW4ocERhdGFfTG93QWNjMSRwcE5leHQpCiAgc3RkX3BwX0hpZ2hBY2MxW1twXV0gPC0gc2QocERhdGFfSGlnaEFjYzEkcHBOZXh0KQogIHN0ZF9wcF9Mb3dBY2MxW1twXV0gPC0gc2QocERhdGFfTG93QWNjMSRwcE5leHQpCiAgCiAgbWVhbl9wcF9IaWdoQWNjMltbcF1dIDwtIG1lYW4ocERhdGFfSGlnaEFjYzIkcHBOZXh0KQogIG1lYW5fcHBfTG93QWNjMltbcF1dIDwtIG1lYW4ocERhdGFfTG93QWNjMiRwcE5leHQpCiAgc3RkX3BwX0hpZ2hBY2MyW1twXV0gPC0gc2QocERhdGFfSGlnaEFjYzIkcHBOZXh0KQogIHN0ZF9wcF9Mb3dBY2MyW1twXV0gPC0gc2QocERhdGFfTG93QWNjMiRwcE5leHQpCiAgCiAgbWVhbl9wcF9IaWdoQWNjM1tbcF1dIDwtIG1lYW4ocERhdGFfSGlnaEFjYzMkcHBOZXh0KQogIG1lYW5fcHBfTG93QWNjM1tbcF1dIDwtIG1lYW4ocERhdGFfTG93QWNjMyRwcE5leHQpCiAgc3RkX3BwX0hpZ2hBY2MzW1twXV0gPC0gc2QocERhdGFfSGlnaEFjYzMkcHBOZXh0KQogIHN0ZF9wcF9Mb3dBY2MzW1twXV0gPC0gc2QocERhdGFfTG93QWNjMyRwcE5leHQpCiAgCiAgbWVhbl9wcF9IaWdoQWNjNFtbcF1dIDwtIG1lYW4ocERhdGFfSGlnaEFjYzQkcHBOZXh0KQogIG1lYW5fcHBfTG93QWNjNFtbcF1dIDwtIG1lYW4ocERhdGFfTG93QWNjNCRwcE5leHQpCiAgc3RkX3BwX0hpZ2hBY2M0W1twXV0gPC0gc2QocERhdGFfSGlnaEFjYzQkcHBOZXh0KQogIHN0ZF9wcF9Mb3dBY2M0W1twXV0gPC0gc2QocERhdGFfTG93QWNjNCRwcE5leHQpCn0KCmBgYAoKYGBge3J9CnBsdF9BbGxBY2MgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMocGx0X0FsbEFjYykgPC0gcGVyc29ucwoKQ09MT1JfQUNDID0gIiMwMkEzQzgiCkNPTE9SX1BQID0gIiNGMjhFOEUiCkNPTE9SX0JSQUtFID0gIiM4ODg4ODgiCgp5MSA8LSBsaXN0KAogIHRpY2tmb250ID0gbGlzdChjb2xvciA9IENPTE9SX0FDQyksCiAgdGl0bGU9IkRlZ3JlZSIsCiAgcmFuZ2U9YygwLCBtYXgoYWxsX0RyaXZlMyRBY2NlbGVyYXRpb24pKQopCnkyIDwtIGxpc3QoCiAgdGlja2ZvbnQgPSBsaXN0KGNvbG9yID0gQ09MT1JfUFApLAogIG92ZXJsYXlpbmcgPSAieSIsCiAgc2lkZSA9ICJyaWdodCIsCiAgdGl0bGUgPSAiTG9nIFBlcnNwaXJhdGlvbiIsCiAgc2hvd2dyaWQgPSBGQUxTRSwKICByYW5nZT1jKC0wLjYsIDAuOSkKICAjIHJhbmdlPWMobWluKGFsbF9Ecml2ZTMkcHBMb2dOb3JtYWxpemVkKSwgbWF4KGFsbF9Ecml2ZTMkcHBMb2dOb3JtYWxpemVkKSkKKQoKZm9yIChwIGluIHBlcnNvbnMpIHsKICBwRGF0YSA8LSBhbGxfRHJpdmUzWyhhbGxfRHJpdmUzJFN1YmplY3Q9PWFzLmludGVnZXIocCkgfCBhbGxfRHJpdmUzJFN1YmplY3Q9PXApLF0KICBwRGF0YV9zZWcwIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0wLF0KICBwRGF0YV9zZWcxIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0xICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMTEwLF0KICBwRGF0YV9zZWcyIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0yICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMjUwLF0KICBwRGF0YV9zZWczIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0zICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMzUwLF0KICBwRGF0YV9zZWc0IDwtIHBEYXRhW3BEYXRhJFBoYXNlPT00ICYgcERhdGEkQWN0aXZpdHk9PTMsXQogIAogIHBsb3RfQWNjIDwtIHBsb3RfbHkocERhdGEsIHggPSB+VGltZSwgaGVpZ2h0PTQwMCwgd2lkdGg9OTAwKSAlPiUKICAgICMgYWRkX3RyYWNlKG5hbWU9IkFjY2VsZXJhdGlvbiIsIHkgPSB+QWNjZWxlcmF0aW9uLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ2xpbmVzJywgbGluZT1saXN0KHdpZHRoPTEuNSwgY29sb3I9Q09MT1JfQUNDKSkgJT4lIAogICAgYWRkX3RyYWNlKG5hbWU9IlBQIiwgeSA9IH5wcExvZ05vcm1hbGl6ZWQsIHR5cGUgPSAnc2NhdHRlcicsIG1vZGUgPSAnbGluZXMnLCBsaW5lPWxpc3Qod2lkdGg9MS41LCBjb2xvcj1DT0xPUl9QUCksIHlheGlzID0gInkyIikgJT4lCiAgICBhZGRfc2VnbWVudHMoeCA9IG1pbihwRGF0YSRUaW1lKSwgeGVuZCA9IG1heChwRGF0YSRUaW1lKSwgeSA9IG1lYW5fcHBbW3BdXSwgeWVuZCA9IG1lYW5fcHBbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAoc3RyYWlnaHQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJkYXJrZ3JheSIsIGRhc2ggPSAnZG90JykpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGEkVGltZSksIHhlbmQgPSBtYXgocERhdGEkVGltZSksIHkgPSBtZWFuX3BwX3NlZzBbW3BdXSwgeWVuZCA9IG1lYW5fcHBfc2VnMFtbcF1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSAieTIiLCBuYW1lPSJBdmcuIFBQICh0dXJuaW5nKSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0iYmxhY2siLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhX3NlZzEkVGltZSksIHhlbmQgPSBtYXgocERhdGFfc2VnMSRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnMVtbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWcxW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKDFzdCBwYXJ0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0icmVkIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgICBhZGRfc2VnbWVudHMoeCA9IG1pbihwRGF0YV9zZWcyJFRpbWUpLCB4ZW5kID0gbWF4KHBEYXRhX3NlZzIkVGltZSksIHkgPSBtZWFuX3BwX3NlZzJbW3BdXSwgeWVuZCA9IG1lYW5fcHBfc2VnMltbcF1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSAieTIiLCBuYW1lPSJBdmcuIFBQICgybmQgcGFydCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9ImdyZWVuIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgICBhZGRfc2VnbWVudHMoeCA9IG1pbihwRGF0YV9zZWczJFRpbWUpLCB4ZW5kID0gbWF4KHBEYXRhX3NlZzMkVGltZSksIHkgPSBtZWFuX3BwX3NlZzNbW3BdXSwgeWVuZCA9IG1lYW5fcHBfc2VnM1tbcF1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSAieTIiLCBuYW1lPSJBdmcuIFBQICgzcmQgcGFydCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhX3NlZzQkVGltZSksIHhlbmQgPSBtYXgocERhdGFfc2VnNCRUaW1lKSwgeSA9IG1lYW5fcHBfc2VnNFtbcF1dLCB5ZW5kID0gbWVhbl9wcF9zZWc0W1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKDR0aCBwYXJ0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0icHVycGxlIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgICBsYXlvdXQoCiAgICAgIHRpdGxlPXBhc3RlMCgiU3ViamVjdCAjIiwgcCksIAogICAgICB4YXhpcz1saXN0KHRpdGxlPSJUaW1lIFtzXSIsIHJhbmdlPWMoMCkpLCAKICAgICAgeWF4aXM9eTEsIAogICAgICB5YXhpczI9eTIsIAogICAgICBtYXJnaW4gPSBsaXN0KGwgPSA1MCwgciA9IDUwLCBiID0gNTAsIHQgPSA1MCwgcGFkID0gNCksCiAgICAgIGxlZ2VuZCA9IGxpc3QoeCA9IDAuNSwgeGFuY2hvciA9ICJjZW50ZXIiLCB5ID0gMC4yLCBiZ2NvbG9yID0gInJnYmEoMCwwLDAsMCkiLCB0aXRsZT0iTWV0cmljIiwgb3JpZW50YXRpb24gPSAiaCIpLAogICAgICBhdXRvc2l6ZSA9IEYKICAgICkKICAKICBwbHRfQWxsQWNjW1twXV0gPC0gcGxvdF9BY2MKfQoKCmh0bWx0b29sczo6dGFnTGlzdChwbHRfQWxsQWNjKQpgYGAKCgpgYGB7cn0KTlVNQkVSX09GX0NMVVNURVJTID0gMwoKY29sb3JfZGFya3BpbmsgPSAiI2U3NTQ4MCIKQ0xVU1RFUl9CUkFOQ0hfQ09MT1JTIDwtIGMoImJsdWUiLCAiZGFya3JlZCIsIGNvbG9yX2RhcmtwaW5rLCAiYmxhY2siKVsxOk5VTUJFUl9PRl9DTFVTVEVSU10KQ0xVU1RFUl9MQUJFTF9DT0xPUlMgPC0gYygiYmx1ZSIsICJkYXJrcmVkIiwgY29sb3JfZGFya3BpbmssICJibGFjayIpWzE6TlVNQkVSX09GX0NMVVNURVJTXQoKZGZQUCA8LSBhcy5kYXRhLmZyYW1lKGNiaW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfbWF4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcxKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWc0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfbWF4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzBfMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcwXzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMF8zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzBfNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzBfMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzBfMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzBfMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzBfNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9IaWdoQWNjKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0xvd0FjYyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0hpZ2hBY2MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9Mb3dBY2MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfSGlnaEFjYzEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfTG93QWNjMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0hpZ2hBY2MxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfTG93QWNjMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9IaWdoQWNjMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9Mb3dBY2MyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfSGlnaEFjYzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9Mb3dBY2MyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0hpZ2hBY2MzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0xvd0FjYzMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9IaWdoQWNjMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0xvd0FjYzMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfSGlnaEFjYzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfTG93QWNjNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0hpZ2hBY2M0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfTG93QWNjNCkKICAgICAgICAgICAgICAgICAgICApKQoKbmFtZXMoZGZQUCkgPC0gYygiTWVhblBQIiwgIlN0ZFBQIiwgCiAgICAgICAgICAgICAgICAgIk1lYW5QUF9TZWcwIiwgIk1lYW5QUF9TZWcxIiwgIk1lYW5QUF9TZWcyIiwgIk1lYW5QUF9TZWczIiwgIk1lYW5QUF9TZWc0IiwgIk1lYW5QUF9TZWdNYXgiLAogICAgICAgICAgICAgICAgICJTdGRQUF9TZWcwIiwgIlN0ZFBQX1NlZzEiLCAiU3RkUFBfU2VnMiIsICJTdGRQUF9TZWczIiwgIlN0ZFBQX1NlZzQiLCAiU3RkUFBfU2VnTWF4IiwKICAgICAgICAgICAgICAgICAiTWVhblBQX1NlZzBfMSIsICJNZWFuUFBfU2VnMF8yIiwgIk1lYW5QUF9TZWcwXzMiLCAiTWVhblBQX1NlZzBfNCIsCiAgICAgICAgICAgICAgICAgIlN0ZFBQX1NlZzBfMSIsICJTdGRQUF9TZWcwXzIiLCAiU3RkUFBfU2VnMF8zIiwgIlN0ZFBQX1NlZzBfNCIsCiAgICAgICAgICAgICAgICAgIk1lYW5QUF9BY2NIaWdoIiwgIiBNZWFuUFBfQWNjTG93IiwgIlN0ZFBQX0FjY0hpZ2giLCAiU3RkUFBfQWNjTG93IiwKICAgICAgICAgICAgICAgICAiTWVhblBQX0FjY0hpZ2gxIiwgIiBNZWFuUFBfQWNjTG93MSIsICJTdGRQUF9BY2NIaWdoMSIsICJTdGRQUF9BY2NMb3cxIiwKICAgICAgICAgICAgICAgICAiTWVhblBQX0FjY0hpZ2gyIiwgIiBNZWFuUFBfQWNjTG93MiIsICJTdGRQUF9BY2NIaWdoMiIsICJTdGRQUF9BY2NMb3cyIiwKICAgICAgICAgICAgICAgICAiTWVhblBQX0FjY0hpZ2gzIiwgIiBNZWFuUFBfQWNjTG93MyIsICJTdGRQUF9BY2NIaWdoMyIsICJTdGRQUF9BY2NMb3czIiwKICAgICAgICAgICAgICAgICAiTWVhblBQX0FjY0hpZ2g0IiwgIiBNZWFuUFBfQWNjTG93NCIsICJTdGRQUF9BY2NIaWdoNCIsICJTdGRQUF9BY2NMb3c0IikKCmJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nIDwtIGFzLm1hdHJpeChkZlBQKQoKZGlzdE1hdHJpeCA8LSBkaXN0KGJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nKQpocmVzdWx0cyA8LSBkaXN0TWF0cml4ICU+JSBoY2x1c3QobWV0aG9kPSJhdmVyYWdlIikKCmhjIDwtIGhyZXN1bHRzICU+JSAKICAgICAgYXMuZGVuZHJvZ3JhbSAlPiUKICAgICAgc2V0KCJub2Rlc19jZXgiLCBOVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JQogICAgICBzZXQoImxhYmVsc19jb2wiLCB2YWx1ZSA9IENMVVNURVJfTEFCRUxfQ09MT1JTLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lCiAgICAgICMgc2V0KCJsZWF2ZXNfcGNoIiwgMTkpICU+JQogICAgICAjIHNldCgibGVhdmVzX2NvbCIsIHZhbHVlID0gYygiZ3JheSIpLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lICAgIAogICAgICBzZXQoImJyYW5jaGVzX2tfY29sb3IiLCB2YWx1ZT1DTFVTVEVSX0JSQU5DSF9DT0xPUlMsIGs9TlVNQkVSX09GX0NMVVNURVJTKQoKcGxvdChoYykKbGVnZW5kKCJ0b3ByaWdodCIsIAogICAgIHRpdGxlPSJEcml2ZT1Nb3RvcmljIFxuSGllcmFjaGljYWwgQ2x1c3RlcmluZyIsCiAgICAgbGVnZW5kID0gYygiR3JvdXAgMSIsICJHcm91cCAyIiwgIkdyb3VwIDMiKSwgCiAgICAgY29sID0gYygiZGFya3JlZCIsICJwaW5rIiAsICJibHVlIiksCiAgICAgcGNoID0gYygyMCwyMCwyMCksIGJ0eSA9ICJuIiwgIHB0LmNleCA9IDEuNSwgY2V4ID0gMC44ICwgCiAgICAgdGV4dC5jb2wgPSAiYmxhY2siLCBob3JpeiA9IEZBTFNFLCBpbnNldCA9IGMoMC40LCAwLjEpKQpgYGAKCiMgQ2x1c3RlcmluZyB3aXRoIFNEIG9mIFBQCmBgYHtyfQpsaWJyYXJ5KGRlbmRleHRlbmQpCgpjbHVzdGVyaW5nRGYgPC0gZGZQUCAlPiUgc2VsZWN0KFN0ZFBQKQpOVU1CRVJfT0ZfQ0xVU1RFUlMgPSAzCgpjb2xvcl9kYXJrcGluayA9ICIjZTc1NDgwIgpDTFVTVEVSX0JSQU5DSF9DT0xPUlMgPC0gYygiZGFya3JlZCIsICJibHVlIiwgInJlZCIpWzE6TlVNQkVSX09GX0NMVVNURVJTXQpDTFVTVEVSX0xBQkVMX0NPTE9SUyA8LSBjKCJkYXJrcmVkIiwgImJsdWUiLCAicmVkIilbMTpOVU1CRVJfT0ZfQ0xVU1RFUlNdCgpiZWhhdmlvcmFsTWF0cml4Q2x1c3RlcmluZyA8LSBhcy5tYXRyaXgoY2x1c3RlcmluZ0RmKQpyb3duYW1lcyhiZWhhdmlvcmFsTWF0cml4Q2x1c3RlcmluZykgPC0gcGFzdGUwKCIjIiwgcGVyc29ucykKZGlzdE1hdHJpeCA8LSBkaXN0KGJlaGF2aW9yYWxNYXRyaXhDbHVzdGVyaW5nKQpocmVzdWx0cyA8LSBkaXN0TWF0cml4ICU+JSBoY2x1c3QKCmhjIDwtIGhyZXN1bHRzICU+JSAKICAgICAgYXMuZGVuZHJvZ3JhbSAlPiUKICAgICAgc2V0KCJub2Rlc19jZXgiLCBOVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JQogICAgICBzZXQoImxhYmVsc19jb2wiLCB2YWx1ZSA9IENMVVNURVJfTEFCRUxfQ09MT1JTLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lCiAgICAgICMgc2V0KCJsZWF2ZXNfcGNoIiwgMTkpICU+JQogICAgICAjIHNldCgibGVhdmVzX2NvbCIsIHZhbHVlID0gYygiZ3JheSIpLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykgJT4lICAgIAogICAgICBzZXQoImJyYW5jaGVzX2tfY29sb3IiLCB2YWx1ZT1DTFVTVEVSX0JSQU5DSF9DT0xPUlMsIGs9TlVNQkVSX09GX0NMVVNURVJTKQoKcGxvdChoYykKbGVnZW5kKCJ0b3ByaWdodCIsIAogICAgIHRpdGxlPSJEcml2ZT1Nb3RvcmljIFxuQ2hhbmdlIG9mIEFyb3VzYWwiLAogICAgIGxlZ2VuZCA9IGMoIkV4Y2VwdGlvbmFsIFNEIiAsICJMb3cgU0QiICwgIkhpZ2ggU0QiKSwgCiAgICAgY29sID0gYygiZGFya3JlZCIsICJibHVlIiAsICJyZWQiKSwKICAgICBwY2ggPSBjKDIwLDIwLDIwKSwgYnR5ID0gIm4iLCAgcHQuY2V4ID0gMS41LCBjZXggPSAwLjggLCAKICAgICB0ZXh0LmNvbCA9ICJibGFjayIsIGhvcml6ID0gRkFMU0UsIGluc2V0ID0gYygwLjAsIDAuMSkpCmBgYAoKYGBge3J9CmxpYnJhcnkoY2x1c3RlcikKc2lsaG91ZXR0ZV9zY29yZSA8LSBmdW5jdGlvbihrKXsKICBrbSA8LSBrbWVhbnMoY2x1c3RlcmluZ0RmLCBjZW50ZXJzID0gaywgbnN0YXJ0PTI1KQogIHNzIDwtIHNpbGhvdWV0dGUoa20kY2x1c3RlciwgZGlzdChjbHVzdGVyaW5nRGYpKQogIG1lYW4oc3NbLCAzXSkKfQprIDwtIDI6MTAKYXZnX3NpbCA8LSBzYXBwbHkoaywgc2lsaG91ZXR0ZV9zY29yZSkKcGxvdChrLCB0eXBlPSdiJywgYXZnX3NpbCwgeGxhYj0nTnVtYmVyIG9mIGNsdXN0ZXJzJywgeWxhYj0nQXZlcmFnZSBTaWxob3VldHRlIFNjb3JlcycsIGZyYW1lPUZBTFNFKQpgYGAKCmBgYHtyfQojIFN0b3JlIGNsdXN0ZXJpbmcgZGF0YQpkZnggPC0gZGZQUApkZnggPC0gY2JpbmQocGVyc29ucywgZGZ4KQpuYW1lcyhkZngpIDwtIGMoIlN1YmplY3QiICwgbmFtZXMoZGZQUCkpCndyaXRlLmNzdihkZngsIG91dHB1dEZpbGUsIHJvdy5uYW1lcyA9IEYpCmBgYAoKIyMgTGluZWFyIE1vZGVsCmBgYHtyfQpzYW1wbGVkRGF0YSA8LSBnZXRTYW1wbGVTZWdtZW50ZWREYXRhKE5BLCBhbGxfRHJpdmUzLCB3aW5kb3c9V0lORE9XX1RJTUUpCmxpbmVhck1vZGVsT25saW5lIDwtIGxtZXIocHBOZXh0IH4gCiAgICAgICAgICAgICAgKDEgfCBTdWJqZWN0KQogICAgICAgICAgICAgICsgU3BlZWRfdQogICAgICAgICAgICAgICsgU3BlZWRfc3RkCiAgICAgICAgICAgICAgKyBBY2NfdQogICAgICAgICAgICAgICsgQWNjX3N0ZAogICAgICAgICAgICAgICsgQnJha2VfdQogICAgICAgICAgICAgICsgQnJha2Vfc3RkCiAgICAgICAgICAgICAgKyBTdGVlcmluZ191CiAgICAgICAgICAgICAgKyBTdGVlcmluZ19zdGQsIAogICAgICAgICAgICBkYXRhPXNhbXBsZWREYXRhLCBSRU1MID0gVCkKCiMgbG1lcihwcExvZ05vcm1hbGl6ZWQgfiAoMSB8IFN1YmplY3QpICsgU3BlZWRfdSArIFNwZWVkX3N0ZCArIEFjY191ICsgQWNjX3N0ZCArIEJyYWtlX3UgKyBCcmFrZV9zdGQgKyBTdGVlcmluZ191ICsgU3RlZXJpbmdfc3RkICsgSFIgKyBCUiwgZGF0YSA9IHBEYXRhLCBSRU1MID0gVCkKCiMgYW5vdmEobW9kZWwpCnN1bW1hcnkobGluZWFyTW9kZWxPbmxpbmUpCnBsb3QobGluZWFyTW9kZWxPbmxpbmUpCmBgYA==